@fabiosantoscode
Yup, another example is how *NIX systems typically manage 32-bit support. The kernel provides a 32-bit system-call layer that forwards to the 64-bit version, userspace runs in the CPU's 32-bit mode. Windows went for a much heavier approach where most DLLs are provided as 64-bit code with 32-bit thunks that run in a Windows-on-Windows layer, with a 64-bit userspace process that puts the legacy code in the low 4 GiB and runs it in 32-bit mode.
I think the problem with a lot of newer things is that they're not really programs, they're components in a distributed system. You may be able to run a ten-year-old Android app in an emulator quite easily but it will expect to connect to a bunch of online services that might not exist anymore. So now you need to write compatibility layers for them. And you need a network proxy because it has very old TLS certificates and so can't establish authenticity of remote systems. And it probably has a bunch of vulnerabilities so you need to sandbox it and its network access.
Most MacOS 9 (or Windows 95) apps talked to the user and the filesystem, not the network. Xbox games that talk to a network do so via a carefully controlled channel. The attack surface is much smaller, so the risk from running insecure systems is much less.